use std::path::{Path, PathBuf};
use std::fs::{OpenOptions};
use models::{Bucket, BucketRequest};
use bincode;

pub fn get_path_for_bucket_request(br: &BucketRequest) -> PathBuf {
  let lowercased_symbol = br.symbol.to_ascii_lowercase();
  let period = "5m";
  let mut path: PathBuf =
    [".buckets", lowercased_symbol.as_str(), period].iter().collect();
  path.set_extension("bin");
  println!("path: {:?}", path);
  path
}

fn assure_directories_exist(dir_only_path: &Path) {
  use std::fs::DirBuilder;
  DirBuilder::new()
    .recursive(true)
    .create(dir_only_path).unwrap();
}

pub fn read_buckets(br: &BucketRequest) -> Vec<Bucket> {
  let path = get_path_for_bucket_request(br);
  {
    let dir_path = &path.parent().unwrap();
    assure_directories_exist(dir_path);
  }
  if path.exists() {
    let file = OpenOptions::new()
      .read(true)
      .write(true)
      .open(path)
      .unwrap();
    bincode::deserialize_from(file)
      .unwrap_or_else(
        |err| panic!("deserialization from disk failed: {}", err)
        )
  } else {
    Vec::new()
  }
}

pub fn write_buckets(br: &BucketRequest, bs: &Vec<Bucket>) {
  let path = get_path_for_bucket_request(br);
  {
    let dir_path = &path.parent().unwrap();
    assure_directories_exist(dir_path);
  }
  let file = OpenOptions::new()
    .write(true)
    .create(true)
    .open(path)
    .unwrap();
  bincode::serialize_into(file, bs)
    .unwrap_or_else(|err| panic!("serialization to disk failed: {}", err));
}
